package tool;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class XmlSAXTool {

    static final Logger logger = Logger.getLogger(XmlSAXTool.class);
    private List<String> ahrefs;

    XmlSAXTool() {
        ahrefs = new ArrayList<String>();
    }

    class SAXReaderHandler extends DefaultHandler {
        /*
         * 方法覆盖描述：在xml中读取超链接地址。 (non-Javadoc)
         * @see
         * org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
         * java.lang.String, java.lang.String, org.xml.sax.Attributes)
         */
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) {
            logger.info(uri + "-" + localName + "-" + qName + "-" + attributes);
            String href = attributes.getValue("href");
            if ("a".equals(qName) && !StringUtils.isEmpty(href)) {
                ahrefs.add(href);
            }
        }
    }

    public static void findTargetElement(String xmlDir, String xpath) {
        try {
            InputStream in = XmlSAXTool.class.getResourceAsStream(xmlDir);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document doc = builder.parse(in);
            XPath path = XPathFactory.newInstance().newXPath();
            NodeList nodes = (NodeList) path.evaluate(xpath, doc, XPathConstants.NODESET);
            for (int i=0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                logger.info(node.getNodeValue());
            }
            in.close();
        } catch (XPathExpressionException xpe) {
            logger.error(xpe);
        } catch (ParserConfigurationException pe) {
            logger.error(pe);
        } catch (SAXException saxe) {
            logger.error(saxe);
        } catch (IOException ioe) {
            logger.info(ioe);
        } 
    }

    public List<String> getAhrefs() {
        return ahrefs;
    }

    public XmlSAXTool parseToXml(String url) {
        try {
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            SAXReaderHandler handler = new SAXReaderHandler();
            parser.parse(url, handler);
        } catch (ParserConfigurationException pce) {
            logger.error(pce);
        } catch (SAXException saxe) {
            logger.error(saxe);
        } catch (IOException ioe) {
            logger.error(ioe);
        }

        return this;
    }

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        /*
         * List<String> ahrefs = new
         * XmlSAXTool().parseToXml("src/main/resources/conf/xml/test.xml").
         * getAhrefs(); for (String href : ahrefs) { logger.info(href); }
         * 
         * Desktop desk = Desktop.getDesktop(); URI url = new
         * URI(ahrefs.get(1)); desk.browse(url);
         */
        // -------------------------------------------------
        findTargetElement("/conf/xml/test.xml", "/root/People/@id");
    }
}
